﻿using System.Linq;
using System.Xml;
using System.Xml.Schema;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using XmlStudio.DataLayer;
using XmlStudio.Interfaces;

namespace XmlStudio.Tests {

    /// <summary>
    ///This is a test class for BigXmlDocumentTest and is intended
    ///to contain all BigXmlDocumentTest Unit Tests
    ///</summary>
    [TestClass()]
    public class BigXmlDocumentTest {
        #region Fields
        private TestContext testContextInstance;
        #endregion

        #region Properties
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }
        #endregion

        #region Additional test simpleTypes
        // 
        //You can use the following additional simpleTypes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        #region Constructor tests
        /// <summary>
        /// A test for BigXmlDocument Constructor.
        ///</summary>
        [TestMethod()]
        public void BigXmlDocumentConstructor01Test() {
            var doc = new BigXmlDocument(Common.PathTest1);
        }
        #endregion

        #region GetRootElementTests
        /// <summary>
        /// Test to get the root element of the document using BigXmlDocument.
        /// </summary>
        [TestMethod()]
        public void BigXmlDocumentGetRootElementTest01() {
            var doc = new BigXmlDocument(Common.PathTest1);
            BigXmlNode root = doc.Root;
            Assert.IsNotNull(root);
            Assert.AreEqual<string>("root", root.Name);
        }

        [TestMethod()]
        [ExpectedException(typeof(XmlException))]
        public void BigXmlDocumentGetRootElementTest02() {
            var doc = new BigXmlDocument(Common.PathTest3);
            BigXmlNode root = doc.Root;
            //Assert.IsNull(root);
        }
        #endregion

        #region GetChildNodesTests
        /// <summary>
        /// Test for GetChildNodes() method.
        /// </summary>
        [TestMethod()]
        public void GetChildNodesTest01() {
            var doc = new BigXmlDocument(Common.PathTest4);
            var nodes = doc.GetChildNodes(new int[] { 1 }, string.Empty);
            Assert.AreEqual<int>(2, nodes.Count());

            var node1 = nodes.ElementAt(0);
            var node2 = nodes.ElementAt(1);

            Assert.AreEqual<string>("table", node1.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("h", node1.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("h:table", node1.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3.org/TR/html4/", node1.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("table", node2.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node2.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:table", node2.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node2.XmlNode.CreateNavigator().NamespaceURI);
        }

        /// <summary>
        /// Test for GetChildNodes() method.
        /// </summary>
        [TestMethod()]
        public void GetChildNodesTest02() {
            var doc = new BigXmlDocument(Common.PathTest4);

            var nodes = doc.GetChildNodes(new int[] { 1, 1, 1 }, string.Empty);
            Assert.AreEqual<int>(2, nodes.Count());

            var node1 = nodes.ElementAt(0);
            var node2 = nodes.ElementAt(1);

            Assert.AreEqual<string>("td", node1.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("h", node1.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("h:td", node1.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3.org/TR/html4/", node1.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("td", node2.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("h", node2.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("h:td", node2.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3.org/TR/html4/", node2.XmlNode.CreateNavigator().NamespaceURI);
        }

        /// <summary>
        /// Test for GetChildNodes() method.
        /// </summary>
        [TestMethod()]
        public void GetChildNodesTest03() {
            var doc = new BigXmlDocument(Common.PathTest4);

            var nodes = doc.GetChildNodes(new int[] { 1, 2, 4 }, string.Empty);
            Assert.AreEqual<int>(3, nodes.Count());

            var node1 = nodes.ElementAt(0);
            var node2 = nodes.ElementAt(1);
            var node3 = nodes.ElementAt(2);

            Assert.AreEqual<string>("name", node1.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("g", node1.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("g:name", node1.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/geography", node1.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("language", node2.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("g", node2.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("g:language", node2.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/geography", node2.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("width", node3.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node3.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:width", node3.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node3.XmlNode.CreateNavigator().NamespaceURI);
        }

        /// <summary>
        /// Test for GetChildNodes() method.
        /// </summary>
        [TestMethod()]
        public void GetChildNodesTest04() {
            var doc = new BigXmlDocument(Common.PathTest4);

            var root = (BigXmlNodeInternal)doc.Root;

            var nodes = doc.GetChildNodes(root, string.Empty);
            Assert.AreEqual<int>(2, nodes.Count());

            var node1 = nodes.ElementAt(0);
            var node2 = nodes.ElementAt(1);

            Assert.AreEqual<string>("table", node1.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("h", node1.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("h:table", node1.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3.org/TR/html4/", node1.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("table", node2.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node2.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:table", node2.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node2.XmlNode.CreateNavigator().NamespaceURI);
        }

        /// <summary>
        /// Test for GetChildNodes() method.
        /// </summary>
        [TestMethod()]
        public void GetChildNodesTest05() {
            var doc = new BigXmlDocument(Common.PathTest4);

            var fTable = doc.GetChildNodes(new int[] { 1 }, "2").ElementAt(1);

            var nodes = doc.GetChildNodes(fTable, string.Empty);

            var node1 = nodes.ElementAt(0);
            var node2 = nodes.ElementAt(1);
            var node3 = nodes.ElementAt(2);
            var node4 = nodes.ElementAt(3);

            Assert.AreEqual<string>("name", node1.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node1.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:name", node1.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node1.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("width", node2.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node2.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:width", node2.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node2.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("length", node3.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("f", node3.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("f:length", node3.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/furniture", node3.XmlNode.CreateNavigator().NamespaceURI);

            Assert.AreEqual<string>("childTable", node4.XmlNode.CreateNavigator().LocalName);
            Assert.AreEqual<string>("g", node4.XmlNode.CreateNavigator().Prefix);
            Assert.AreEqual<string>("g:childTable", node4.XmlNode.CreateNavigator().Name);
            Assert.AreEqual<string>("http://www.w3schools.com/geography", node4.XmlNode.CreateNavigator().NamespaceURI);
        }
        #endregion

        #region Other tests
        ///// <summary>
        ///// Test for GetAddressesByParentAndRange().
        ///// </summary>
        //[TestMethod()]
        //public void GetAddressesByParentAddressAndRangeTest()
        //{
        //    var addresses = BigXmlDocument.GetAddressesByParentAndRange(new int[] { 1 }, "1-3");
        //    Assert.IsNotNull(addresses);
        //    Assert.AreEqual<int>(3, addresses.Count());

        //    var addr1 = addresses.ElementAt(0);
        //    var addr2 = addresses.ElementAt(1);
        //    var addr3 = addresses.ElementAt(2);

        //    Assert.IsTrue(addr1.SequenceEqual(new int[] { 1, 1 }));
        //    Assert.IsTrue(addr2.SequenceEqual(new int[] { 1, 2 }));
        //    Assert.IsTrue(addr3.SequenceEqual(new int[] { 1, 3 }));
        //}
        #endregion
    }
}